import json
from pathlib import Path
from typing import Dict, List, Any, Optional
import logging
from datetime import datetime
from concurrent.futures import ThreadPoolExecutor
import uuid

# 导入各功能模块
from agents.resume_parser import ResumeParser
from agents.knowledge_graph import JobKnowledgeGraph
from agents.rl_optimizer import RLOptimizer
from agents.salary_predictor import SalaryPredictor
from agents.interview_assistant import InterviewAssistant
from agents.career_planner import CareerPlanner
from agents.explainable_ai import ExplainableAI
from data.kafka_pipeline import JobDataPipeline
from agents.distributed_executor import DistributedExecutor

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger("CareerSystem")

class CareerDevelopmentSystem:
    """智能职业发展系统"""
    def __init__(self, config: Dict[str, Any]):
        self.config = config
        self.system_id = f"career-system-{uuid.uuid4().hex[:8]}"
        self.executor = ThreadPoolExecutor(max_workers=8)
        self._init_components()
        self._setup_data_dirs()
        
    def _init_components(self):
        """初始化各功能组件"""
        # 知识图谱
        self.kg = JobKnowledgeGraph()
        
        # 各功能模块
        self.resume_parser = ResumeParser(self.kg)
        self.salary_predictor = SalaryPredictor()
        self.interview_assistant = InterviewAssistant(self.kg)
        self.career_planner = CareerPlanner(self.kg)
        self.explainer = ExplainableAI(self.kg, None)  # 暂时不关联AgentSystem
        
        # 实时数据处理
        self.kafka_pipeline = JobDataPipeline(
            self.config.get("kafka_config", {})
        )
        
        # 分布式计算
        self.dist_executor = DistributedExecutor(
            self.config.get("ray_config", {})
        )
        
        # 强化学习优化器
        self.rl_optimizer = RLOptimizer({
            "num_cpus": self.config.get("ray_config", {}).get("num_cpus", 4),
            "save_path": "b/models/rl"
        })
        
        logger.info("所有系统组件初始化完成")
    
    def _setup_data_dirs(self):
        """设置数据目录结构"""
        Path("b/data/users").mkdir(parents=True, exist_ok=True)
        Path("b/data/jobs").mkdir(parents=True, exist_ok=True)
        Path("b/data/reports").mkdir(parents=True, exist_ok=True)
        Path("b/data/models").mkdir(parents=True, exist_ok=True)
        
    def process_user_journey(self, user_data: Dict[str, Any]) -> Dict[str, Any]:
        """处理用户全周期职业发展流程"""
        user_id = user_data.get("user_id", f"user-{uuid.uuid4().hex[:6]}")
        results = {
            "user_id": user_id,
            "timestamp": datetime.now().isoformat(),
            "phases": {}
        }
        
        try:
            # 阶段1: 简历解析
            if "resume_file" in user_data:
                resume_result = self.resume_parser.parse_resume(
                    user_data["resume_file"]
                )
                results["phases"]["resume_parsing"] = resume_result
                user_data.update({
                    "skills": resume_result.get("skills", []),
                    "experience": self._calculate_experience(
                        resume_result.get("experiences", [])
                    )
                })
            
            # 阶段2: 技能评估
            skill_report = self._assess_skills(user_data)
            results["phases"]["skill_assessment"] = skill_report
            
            # 阶段3: 岗位匹配
            job_recommendations = self._recommend_jobs(user_data)
            results["phases"]["job_recommendations"] = job_recommendations
            
            # 阶段4: 薪酬预测
            salary_analysis = self._analyze_salaries(user_data, job_recommendations)
            results["phases"]["salary_analysis"] = salary_analysis
            
            # 阶段5: 面试准备
            if "target_job" in user_data:
                interview_prep = self._prepare_interview(user_data)
                results["phases"]["interview_preparation"] = interview_prep
            
            # 阶段6: 职业规划
            career_plan = self._plan_career_path(user_data)
            results["phases"]["career_planning"] = career_plan
            
            # 保存用户报告
            self._save_user_report(user_id, results)
            
            return results
            
        except Exception as e:
            logger.error(f"处理用户流程失败: {str(e)}", exc_info=True)
            results["error"] = str(e)
            return results
    
    def _calculate_experience(self, experiences: List[Dict]) -> int:
        """计算总工作经验(年)"""
        if not experiences:
            return 0
            
        # 简单实现: 取最近工作的结束时间与最早工作的开始时间之差
        sorted_exp = sorted(
            experiences,
            key=lambda x: x.get("start_date", "")
        )
        start_date = sorted_exp[0].get("start_date")
        end_date = sorted_exp[-1].get("end_date")
        
        if start_date and end_date:
            try:
                start = datetime.strptime(start_date[:10], "%Y-%m-%d")
                end = datetime.strptime(end_date[:10], "%Y-%m-%d")
                return max(1, (end - start).days // 365)
            except:
                return len(experiences)
        return len(experiences)
    
    def _assess_skills(self, user_data: Dict[str, Any]) -> Dict[str, Any]:
        """评估用户技能"""
        skills = user_data.get("skills", [])
        return {
            "skill_count": len(skills),
            "skill_categories": self._categorize_skills(skills),
            "kg_standardized": self.kg.standardize_skills(skills),
            "assessment_date": datetime.now().isoformat()
        }
    
    def _categorize_skills(self, skills: List[str]) -> Dict[str, List[str]]:
        """技能分类"""
        categories = {
            "programming": [],
            "data": [],
            "devops": [],
            "soft_skills": [],
            "other": []
        }
        
        tech_skills = ["python", "java", "c++", "sql", "javascript"]
        data_skills = ["machine learning", "data analysis", "statistics"]
        devops_skills = ["docker", "kubernetes", "aws", "git"]
        
        for skill in skills:
            skill_lower = skill.lower()
            if skill_lower in tech_skills:
                categories["programming"].append(skill)
            elif skill_lower in data_skills:
                categories["data"].append(skill)
            elif skill_lower in devops_skills:
                categories["devops"].append(skill)
            else:
                categories["other"].append(skill)
                
        return categories
    
    def _recommend_jobs(self, user_data: Dict[str, Any]) -> Dict[str, Any]:
        """推荐适合岗位"""
        # 使用强化学习模型推荐
        state = {
            "user_skills": user_data.get("skills", []),
            "user_experience": user_data.get("experience", 0),
            "target_industry": user_data.get("target_industry"),
            "job_count": 100  # 模拟值
        }
        
        action = self.rl_optimizer.recommend(state)
        
        # 从知识图谱获取岗位详情
        recommended_jobs = self.kg.find_related_jobs(
            user_data.get("skills", []),
            limit=5
        )
        
        return {
            "recommended_jobs": recommended_jobs,
            "rl_action": action,
            "explanation": self.explainer.generate_natural_language({
                "user_skills": user_data.get("skills", []),
                "job_data": recommended_jobs[0] if recommended_jobs else {}
            })
        }
    
    def _analyze_salaries(self, user_data: Dict[str, Any],
                        job_recommendations: Dict[str, Any]) -> Dict[str, Any]:
        """分析推荐岗位的薪酬"""
        predictions = []
        
        for job in job_recommendations.get("recommended_jobs", [])[:3]:
            try:
                prediction = self.salary_predictor.predict_salary({
                    "years_experience": user_data.get("experience", 0),
                    "education_level": user_data.get("education_level", 3),  # 默认本科
                    "skill_count": len(job.get("required_skills", [])),
                    "industry": job.get("industry"),
                    "location_tier": user_data.get("location_tier", 1)  # 默认一线城市
                })
                predictions.append({
                    "job_title": job.get("title"),
                    "company": job.get("company"),
                    "prediction": prediction
                })
            except Exception as e:
                logger.error(f"薪酬预测失败: {str(e)}")
                continue
                
        return {
            "salary_predictions": predictions,
            "average_salary": self._calculate_average(predictions)
        }
    
    def _calculate_average(self, predictions: List[Dict]) -> float:
        """计算平均预测薪资"""
        if not predictions:
            return 0
            
        salaries = [
            p["prediction"]["predicted_salary"] 
            for p in predictions
            if p["prediction"]
        ]
        return sum(salaries) / len(salaries) if salaries else 0
    
    def _prepare_interview(self, user_data: Dict[str, Any]) -> Dict[str, Any]:
        """准备面试"""
        target_job = user_data["target_job"]
        difficulty = user_data.get("interview_difficulty", "medium")
        
        # 生成面试问题
        questions = self.interview_assistant.generate_interview(
            target_job, difficulty
        )
        
        # 创建模拟面试报告
        report = self.interview_assistant.conduct_mock_interview(
            target_job, difficulty
        )
        
        return {
            "target_job": target_job,
            "generated_questions": [
                {
                    "question": q.question_text,
                    "type": q.question_type,
                    "difficulty": q.difficulty
                }
                for q in questions
            ],
            "mock_interview_report": report
        }
    
    def _plan_career_path(self, user_data: Dict[str, Any]) -> Dict[str, Any]:
        """规划职业发展路径"""
        return self.career_planner.generate_development_plan({
            "user_id": user_data.get("user_id", "anonymous"),
            "current_job": user_data.get("current_job", "未填写"),
            "skills": user_data.get("skills", []),
            "target_industry": user_data.get("target_industry"),
            "experience": user_data.get("experience", 0)
        })
    
    def _save_user_report(self, user_id: str, report_data: Dict[str, Any]):
        """保存用户报告"""
        report_file = Path(f"b/data/reports/{user_id}_full_report.json")
        with open(report_file, "w", encoding="utf-8") as f:
            json.dump(report_data, f, ensure_ascii=False, indent=2)
        logger.info(f"用户报告已保存到 {report_file}")
    
    def start_services(self):
        """启动系统服务"""
        logger.info(f"启动智能职业发展系统 {self.system_id}")
        
        # 启动Kafka管道
        self.kafka_pipeline.start()
        
        # 启动强化学习训练 (后台运行)
        self.executor.submit(self.rl_optimizer.train, 20)
        
        logger.info("所有后台服务已启动")
    
    def shutdown(self):
        """关闭系统"""
        logger.info("正在关闭系统...")
        
        # 关闭Kafka管道
        self.kafka_pipeline._shutdown()
        
        # 关闭分布式执行器
        self.dist_executor.shutdown()
        
        # 关闭线程池
        self.executor.shutdown(wait=False)
        
        logger.info("系统关闭完成")

if __name__ == "__main__":
    # 示例配置
    config = {
        "kafka_config": {
            "bootstrap_servers": "localhost:9092",
            "topic": "career_events",
            "group_id": "career_system_group"
        },
        "ray_config": {
            "num_cpus": 4,
            "object_store_memory": 4 * 1024 * 1024 * 1024  # 4GB
        }
    }
    
    # 创建并启动系统
    system = CareerDevelopmentSystem(config)
    system.start_services()
    
    # 示例用户流程
    sample_user = {
        "user_id": "test_user_001",
        "resume_file": "b/data/resumes/sample_resume.pdf",
        "target_industry": "IT",
        "education_level": 4,  # 本科
        "location_tier": 1,    # 一线城市
        "target_job": "Python开发工程师"
    }
    
    try:
        # 处理用户全周期
        print("\n处理用户职业发展流程...")
        results = system.process_user_journey(sample_user)
        
        # 打印摘要
        print("\n===== 职业发展报告摘要 =====")
        print(f"用户ID: {results['user_id']}")
        print(f"分析时间: {results['timestamp']}")
        
        print("\n【技能评估】")
        skills = results["phases"]["skill_assessment"]
        print(f"技能总数: {skills['skill_count']}")
        print("技能分类:", json.dumps(skills["skill_categories"], indent=2, ensure_ascii=False))
        
        print("\n【岗位推荐】")
        jobs = results["phases"]["job_recommendations"]
        print(f"推荐岗位数: {len(jobs['recommended_jobs'])}")
        print("推荐理由:", jobs["explanation"])
        
        print("\n【薪酬预测】")
        salaries = results["phases"]["salary_analysis"]
        print(f"平均预测薪资: ¥{salaries['average_salary']:,.2f}")
        
        # 保持运行
        while True:
            pass
            
    except KeyboardInterrupt:
        system.shutdown()